package copyengine.utils.polygon {
    import copyengine.utils.Random;

    import flash.geom.Point;

    /**
     * 矢量描述的多边形,实现hitTestPoint和randomPointInPolygon用于相应的逻辑计算
     *
     * 每一个Polygon均是由若干个三角形构成(三角形可相交也可不相交)
     */
    public class CEVectorPolygon {

        private var mAllTriangleVector:Vector.<CEVectorTriangle>;
        private var mLength:int;
        private var mLeftTopPoint:Point;
        private var mRightBottomPoint:Point;

        public function CEVectorPolygon() {
            mAllTriangleVector = new Vector.<CEVectorTriangle>();
            mLeftTopPoint = new Point(int.MAX_VALUE, int.MAX_VALUE);
            mRightBottomPoint = new Point(int.MIN_VALUE, int.MIN_VALUE);
        }

        public function addTriangle(_triangle:CEVectorTriangle):void {
            mAllTriangleVector.push(_triangle);
            mLength = mAllTriangleVector.length;
            calculateMinMaxByTriangle(_triangle);
        }

        public function hitTestPoint(_x:Number, _y:Number):Boolean {
            //Step1 AABB
            if (_x >= mLeftTopPoint.x && _x <= mRightBottomPoint.x && _y >= mLeftTopPoint.y && _y <= mRightBottomPoint.y) {
                //Step2 检测每个三角形
                for (var i:int = 0; i < mLength; i++) {
                    if (mAllTriangleVector[i].hitTestPoint(_x, _y)) {
                        return true;
                    }
                }
            }
            return false;
        }

        public function getRandomPointInPolygon(_result:Point):Point {
            var triangle:CEVectorTriangle = mAllTriangleVector[Random.range(0, mLength)];
            return triangle.randomPointInTriangle(_result);
        }

        public function get width():Number {return mRightBottomPoint.x - mLeftTopPoint.x;}

        public function get height():Number {return mRightBottomPoint.y - mLeftTopPoint.y;}

        public function get x():Number {return mLeftTopPoint.x;}

        public function get y():Number {return mLeftTopPoint.y;}

        //========================//
        //==Private  Function
        //=========================//

        private function calculateMinMaxByTriangle(_t:CEVectorTriangle):void {
            calculateMinMaxByPoint(_t.a);
            calculateMinMaxByPoint(_t.b);
            calculateMinMaxByPoint(_t.c);
        }

        private function calculateMinMaxByPoint(_p:Point):void {
            mLeftTopPoint.x = Math.min(_p.x, mLeftTopPoint.x);
            mLeftTopPoint.y = Math.min(_p.y, mLeftTopPoint.y);

            mRightBottomPoint.x = Math.max(_p.x, mRightBottomPoint.x);
            mRightBottomPoint.y = Math.max(_p.y, mRightBottomPoint.y);
        }


    }
}
